import os

import bs4 as bs4
from dotenv import load_dotenv
from langchain.prompts import PromptTemplate
from langchain.chains.combine_documents.stuff import StuffDocumentsChain, LLMChain
from langchain.chains.combine_documents.map_reduce import LLMChain, ReduceDocumentsChain, MapReduceDocumentsChain
from langchain_text_splitters import CharacterTextSplitter
from langchain_community.document_loaders import WebBaseLoader
from langchain_openai import ChatOpenAI

load_dotenv()


# 1.创建模型
model = ChatOpenAI(
    model='qwen-plus',
    api_key=os.getenv("DASHSCOPE_API_KEY"),
    base_url="https://dashscope.aliyuncs.com/compatible-mode/v1",
)

# 通过DocumentLoader加载数据
loader = WebBaseLoader(
    web_paths=['https://lilianweng.github.io/posts/2023-06-23-agent/'],
    bs_kwargs=dict(
        parse_only=bs4.SoupStrainer(class_=('post-header', 'post-title', 'post-content'))
    )
)

docs = loader.load()
# print(docs)

text_splitter = CharacterTextSplitter.from_tiktoken_encoder(chunk_size=1000, chunk_overlap=0)
split_docs = text_splitter.split_documents(docs)

# map阶段
map_template = """以下是一组文档(documents)
"{docs}"
根据这个文档列表，请给出总结摘要："""
map_prompt = PromptTemplate.from_template(map_template)
map_llm_chain = LLMChain(llm=model, prompt=map_prompt)

# reduce阶段（combine和最终reduce）
reduce_template = """以下是一组总结摘要：
"{docs}"
将这些摘要统一成一个最终的、统一的总结摘要："""
reduce_prompt = PromptTemplate.from_template(reduce_template)
reduce_llm_chain = LLMChain(llm=model, prompt=reduce_prompt)

# 定义combine的chain
combine_chain = StuffDocumentsChain(llm_chain=reduce_llm_chain, document_variable_name='docs')

reduce_chain = ReduceDocumentsChain(
    # 最终调用的 chain
    combine_documents_chain=combine_chain,
    # 中间汇总的 chain
    collapse_documents_chain=combine_chain,
    # 将文档分组的最大token数
    token_max=4000,
)

# 合并所有chain
map_reduce_chain = MapReduceDocumentsChain(
    llm_chain=map_llm_chain,
    reduce_documents_chain=reduce_chain,
    document_variable_name='docs',
    return_intermediate_steps=False,
)

result = map_reduce_chain.invoke(split_docs)
print(result['output_text'])

# ### 最终统一总结摘要：
#
# 本文系统性地探讨了**基于大语言模型（LLM）的自主智能代理（Autonomous Agents）**的设计、实现与优化路径，全面分析了从系统架构、核心组件、算法框架到工具集成、外部记忆系统与实际应用的多个关键维度。其核心目标是构建能够自主规划、执行复杂任务、持续学习并高效与环境交互的智能系统，标志着LLM从“语言生成”向“任务驱动”范式的演进。
#
# ---
#
# #### 一、**系统架构与核心能力**
#
# LLM作为智能代理的核心控制器，整合以下三大核心组件，实现高效任务处理与自主行为：
#
# 1. **规划（Planning）**
#    - 通过任务分解与路径搜索，使代理具备多步骤、多目标处理能力。
#    - 主要方法包括：
#      - **Chain of Thought（CoT）**：逐步推理任务结构。
#      - **Tree of Thoughts（ToT）**：在多个路径中搜索最优解。
#      - **LLM+P**：结合外部经典规划器（如PDDL）进行长期任务调度。
#
# 2. **记忆（Memory）**
#    - **短期记忆**：依赖上下文窗口维持当前任务状态。
#    - **长期记忆**：借助外部向量存储与快速检索机制实现信息持久化与复用。
#    - 模拟人类记忆结构，将输入嵌入视为“感觉记忆”，上下文为“短时记忆”，外部存储为“长时记忆”。
#
# 3. **工具使用（Tool Use）**
#    - LLM可调用外部API、数据库、代码执行器等工具，突破模型本身的知识与功能边界。
#    - 工具调用是提升代理自主性与泛化能力的关键，体现人类使用工具以突破限制的智慧本质。
#
# ---
#
# #### 二、**核心算法与推理框架**
#
# 多种算法框架致力于提升代理的推理能力与决策效率，推动任务执行的智能化：
#
# - **ReAct**：结合推理与行动，通过`Thought → Action → Observation`循环推进任务，适用于知识密集型场景。
# - **Reflexion**：引入动态反思机制，通过启发函数检测低效行为或幻觉，并进行策略调整。
# - **Chain of Hindsight（CoH）**：利用历史反馈数据训练模型进行自我改进，迭代优化输出质量。
# - **Algorithm Distillation（AD）**：将强化学习建模为上下文中的行为克隆任务，训练任务无关策略，模拟在线强化学习表现。
#
# ---
#
# #### 三、**外部记忆与高效检索机制**
#
# 为增强代理的长期记忆能力，外部向量存储系统成为关键基础设施。结合以下**近似最近邻（ANN）算法**实现高效检索：
#
# - **LSH（Locality-Sensitive Hashing）**
# - **ANNOY**
# - **HNSW**
# - **FAISS**
# - **ScaNN**
#
# 这些技术共同构成**最大内积搜索（MIPS）**系统，是实现高效外部记忆访问与知识复用的核心。
#
# ---
#
# #### 四、**模块化集成与工具增强型LLM**
#
# LLM通过与外部工具、模块与平台的深度融合，显著提升其推理、计算、实时数据处理与科学探索能力：
#
# - **MRKL系统**：引入模块化架构，LLM作为“控制器”选择合适工具执行特定任务。
# - **TALM 与 Toolformer**：通过微调模型使其学习调用外部API，提升任务执行准确率。
# - **ChatGPT Plugins 与 OpenAI Function Calling**：展示LLM通过插件机制调用第三方服务的实际应用。
# - **HuggingGPT**：LLM作为任务规划器，协调多个HuggingFace模型完成复杂任务，流程包括任务分解 → 模型选择 → 执行 → 结果整合。
#
# ---
#
# #### 五、**评估与应用验证**
#
# 多个基准与实际应用验证了LLM代理在专业领域与自主行为系统中的潜力：
#
# - **API-Bank**：评估LLM在多层级任务中的API调用能力。
# - **ChemCrow**：结合GPT-4与化学专用工具，基于ReAct框架完成药物设计等任务。
# - **科学探索代理**：LLM可自主进行趋势分析、靶点选择、化合物设计与合成。
# - **生成代理架构**（Park et al., 2023）：通过记忆流、反思机制与行为规划模块，使代理具备长期记忆与社交行为模拟能力。
# - **AutoGPT等自主代理**：展示无需人工干预完成任务的潜力，但也面临稳定性与安全性挑战。
#
# ---
#
# #### 六、**智能任务执行平台与性能优化**
#
# 面向实际应用，构建多功能、自动化操作的智能平台成为趋势：
#
# - 支持信息获取、代理管理、文件操作、代码处理、内容生成等20余种命令。
# - 核心资源包括互联网访问、长期记忆管理、GPT代理协作与文件输出。
# - 强调**反思与自我优化机制**，通过回顾历史操作提升效率，同时最小化执行成本。
#
# ---
#
# #### 七、**典型项目案例：GPT-Engineer**
#
# **GPT-Engineer** 是一个基于LLM的智能代理项目，旨在根据用户提供的自然语言任务描述，自动生成完整的代码仓库。其核心流程包括：
#
# - **任务澄清**：通过多轮交互逐步明确用户需求，涵盖功能细节、模块划分、控制方式等关键要素。
# - **代码生成规范制定**：定义清晰的文件结构、代码注释与文档规范。
# - **代码实现**：生成结构化、可维护的代码，支持模块化开发与后续迭代。
#
# 技术实现上，GPT-Engineer 依赖于结构化推理方法（如 Chain of Thought、ReAct）提升模型逻辑能力，并通过调用外部工具与API扩展其功能边界。其系统架构体现了模块化设计思想，结合记忆、规划与执行能力，模拟人类开发者的工作流程。
#
# ---
#
# #### 八、**挑战与未来方向**
#
# 尽管LLM代理展现出巨大潜力，但仍面临以下挑战：
#
# - **任务复杂性与准确性**：长链任务执行易出错，需引入反思与修正机制。
# - **用户交互与反馈机制**：需在生成与澄清之间找到平衡。
# - **代码质量与可维护性**：生成代码需符合工程规范，便于后续迭代。
# - **通用性与可扩展性**：当前系统仍受限于特定场景，难以泛化至复杂工程任务。
# - **系统可解释性与安全性**：提升透明度，确保代理行为可控、可信。
#
# 未来发展方向包括：
#
# - 提升工具调用的准确性与稳定性；
# - 优化模块间协作机制；
# - 增强系统可解释性与安全性；
# - 推动LLM在专业领域（如化学、医药）与自主代理系统中的深度应用；
# - 实现与真实世界的深度交互与持续学习。
#
# ---
#
# ### 总结：
#
# LLM与外部工具、模块及代理系统的深度融合，标志着人工智能系统正迈向**更智能、更模块化、更实用化**的新阶段。这一方向不仅推动了AI在多个实际场景的应用落地，也为构建具备类人认知能力的通用人工智能（AGI）奠定了坚实基础，具备广泛的应用前景与深远的社会影响。

